Mirror裡Tank的範例對於了解Mirror有相當的助益,今天就花些時間將基本的流程的建構起來。大致上也和Tank的起始流程相似。不過目前開始暫定不用達到最少人數,且沒有結束的判定,也就是說今天要實現的行為是只有開始而沒有結束的流程。
原先空蕩蕩的場景了連地板都沒有,所以今天一開始就先放一個地板,讓代表玩家的方塊不像是浮在空中一般。先預留之後場景設置的彈性,利用Unity給予的ProBuilder加個地板。不過空蕩歸空蕩,先不放置會阻擋行進的障礙物,在連線的概念下,處理障礙物可能會花去不少時間,現在先以視覺呈現和定比例為主。
場景的範圍增加後,若是不移動Camera,則Player會被縮的很小,因此今天也試著將Camera跟隨這部份加進來。用一般的跟隨會有一些問題要自行處理,不過短時程的連線遊戲開發有可能會遇到更多花時間的麻煩事,所以就直接用Unity給的Cinemachine Virtual Camera來進行追蹤本地端的玩家。在Camera上要先行加入Cinemachine Brain元件,而後在Cinemahine選單裡選擇Virtual Camera,就可以產生一個被Brain控管的鏡頭。
有一個使用virtual camera的小技巧,那就是一開始可以先放一個暫代物件(遊戲在執行時會移除)去調整,等到調整後於執行時直接套用即可。其實在Cinemachine的用法上本來也就是針對現在場景中有的物件去做鏡頭跟隨,所以會有虛擬角色的調整方式。這裡暫不切入,之後會有一段時間調整過場時會在好好的研究Cinemachine的用法。
回到和連線相關的部份。鏡頭和UI是類似的,都只在Client端才有,且只代表本機的Client,也就Local Player才能操控或表示。以現在從Mirror的二個範例來看,做法就有二種
public override void OnStartLocalPlayer()
ClientScene.localPlaeyr
好像沒有特別標註什麼情況下放在何處,鏡頭就先以ClientScene.localPlaeyr
方式處理。直接放在第一次assign local player的行為裡,雖然不是最好的地方,但現下看起來還算可以。
private void AssignLocalPlayer()
{
if (!_localPlayer == null) return;
if (ClientScene.localPlayer == null) return;
_localPlayer = ClientScene.localPlayer.GetComponent<Player>();
// Extract to elsewhere might be better
var cvc = virtualCameraGO.GetComponent<CinemachineVirtualCamera>();
if (cvc != null)
{
cvc.Follow = _localPlayer.transform;
cvc.LookAt = _localPlayer.transform;
}
}
一台直接跑起來好像沒有問題
但是連線的迷人之處就是至少要二台看起來正確才是正確的,所以額外建置後執行是少不了的。實際跑起來也看起來很像是正確的。
鏡頭調整完後就是將數值顯示到UI上,到這裡都和Demo大同小異,用了UniRx的方式進行數值更正後顯示到UI上,但都沒有特別之處。現在的版本在加上了UI後,只要被攻擊,就會直接扣掉一定的值。可以從如下的畫面看到。
而在了解Mirror元件時也試了NetworkStartPosition
,這個元件加上去後,Player進入到這個場景時的位置就會隨機的從這些物件的位置進行選擇。這裡畫綠線的選項只有Random和Round Robin,也就是只有隨機和循環,若是需要按照團隊方式進行生成位置選擇,就要再研究看看怎麼進行。
雖然扣血的功能有了,也顯示在UI上,但血扣到零以下的部份還沒有處理。不過這個部份是和遊戲的流程有關,流程又和實際的玩法有相關,這裡就暫時打住,先行了解其它部份的用法。其中最重要的還是角色控制器,連線版本的。另外,就是要將建置後的執行檔放在某處,以供下載,不過這部份不算是當務之急,畢竟遊戲開發有很長的一段時間畫面和控制性都很陽春。待之後某個階段時再來處理。